#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <inttypes.h>
#include <pthread.h>
#include <stddef.h>
#include <unistd.h>

enum logLevelEnum
{
    logLevelFatal = 0,
    logLevelError,
    logLevelWarn,
    logLevelInform,
    logLevelDebug,
    logLevelTrace,
};
extern int logLevelParam;

#define printf_common(lev, fmt, lprt, ...)                                                                             \
    do                                                                                                                 \
    {                                                                                                                  \
        if (lev <= logLevelParam)                                                                                      \
        {                                                                                                              \
            struct timeval tnow;                                                                                       \
            struct tm *tmnow;                                                                                          \
            gettimeofday(&tnow, NULL);                                                                                 \
            tmnow = localtime(&tnow.tv_sec);                                                                           \
            printf("[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s,%d]" fmt "\n", tmnow->tm_year + 1900, tmnow->tm_mon + 1, \
                   tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec, (int)tnow.tv_usec / 1000,             \
                   lprt, __FILE__, __LINE__, ##__VA_ARGS__);                                                           \
        }                                                                                                              \
    } while (0);
#define printffatal(fmt, ...) printf_common(logLevelFatal, fmt, "fat", ##__VA_ARGS__)
#define printerror(fmt, ...) printf_common(logLevelError, fmt, "err", ##__VA_ARGS__)
#define printwarn(fmt, ...) printf_common(logLevelWarn, fmt, "war", ##__VA_ARGS__)
#define printinform(fmt, ...) printf_common(logLevelInform, fmt, "inf", ##__VA_ARGS__)
#define printdebug(fmt, ...) printf_common(logLevelDebug, fmt, "dbg", ##__VA_ARGS__)
#define printtrace(fmt, ...) printf_common(logLevelTrace, fmt, "tra", ##__VA_ARGS__)

#define logfatal(fmt, ...) printffatal(fmt, ##__VA_ARGS__)
#define logerror(fmt, ...) printerror(fmt, ##__VA_ARGS__)
#define logwarn(fmt, ...) printwarn(fmt, ##__VA_ARGS__)
#define loginform(fmt, ...) printinform(fmt, ##__VA_ARGS__)
#define logdebug(fmt, ...) printdebug(fmt, ##__VA_ARGS__)
#define logtrace(fmt, ...) printtrace(fmt, ##__VA_ARGS__)

// 获得成员大小
#define MEMBER_SIZE(type, member) (sizeof(((type *)0)->member))
// 获得成员偏移长度
#define MEMBER_OFFSET(type, member) ((int)(&(((type *)0)->member)))
// 通过成员地址找到结构体变量地址。
#define container_of(ptr, type, member) ((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
// 求数组长度
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
// 将整数、浮点数控制在一个范围。
#define LIMIT_VAL(a, min, max) ((a) > (max) ? (max) : ((a) < (min) ? (min) : (a)))
// 循环加
#define CYCLE_ADD(a, add, len) (((a) + (add)) % (len))
// 交换整形数据宏
#define SWAP_BASE_VAL(a, b) (a ^= b, b ^= a, a ^= b)

// clock函数数据不对。
// #define cTimeDefine(ctimeName) clock_t ctimeName;
// #define cTimeBegin(ct) (ct = clock())
// #define cTimeDefWithBegin(ctimeName) double ctimeName = clock();
// #define cTimeRunUs(ct) ((double)clock() - ct)
// #define cTimeRunMs(ct) ((double)(cTimeRunUs(ct) / 1000))
// #define cTimeRunSec(ct) ((double)(cTimeRunUs(ct) / CLOCKS_PER_SEC))
uint64_t systemNowNs();
uint64_t systemNowUs();
uint64_t systemNowMs();
#define timerMsDefine(ctimeName) uint64_t ctimeName;
#define timerMsBegin(ct) (ct = systemNowMs())
#define timerMsDefBegin(ctimeName) uint64_t ctimeName = systemNowMs();
#define timerMsRunMs(ct) (systemNowMs() - ct)
#define timerMsRunSec(ct) (timerMsRunMs(ct) / 1000)

int memcpypro(void *dest, size_t destsize, const void *src, size_t srcsize);
int hexBufferToReadableString(const char *inbuf, int insize, char *outbuffer, int outsize, int littleCharFlag);
uint8_t calculateUint8CrcSummation(const uint8_t *inbuffer, uint32_t insize);
uint16_t calculateUint16CrcSummation(const uint8_t *inbuffer, uint32_t insize);
int readLocalFile(const char *filepath, char *readbuff, int readsize);
int writeLocalFile(const char *filepath, const char *writebuff, int writesize);

uint8_t calculateUint8CrcHash(const uint8_t *ptr, int len);
uint16_t calculateUint16CrcHash(const uint8_t *data, int length);
uint32_t calculateUint32CrcHash(const uint8_t *buf, int size);
